package com.luobr.backend.manage;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.RandomUtil;
import com.luobr.backend.common.ResponseCode;
import com.luobr.backend.config.OssClientConfig;
import com.luobr.backend.constant.ImageConstant;
import com.luobr.backend.exception.BusinessException;
import com.luobr.backend.exception.ThrowUtils;
import com.luobr.backend.model.dto.image.ImageInfoResult;
import com.luobr.backend.model.dto.image.ImageParseResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.File;
import java.util.Date;

/**
 * @author: 罗念笙
 * @date: 2025/2/24 21:50
 * 图片管理（已经废弃，改用模板类型设计实现 URL 和 文件形式上传）
 */
@Slf4j
@Service
@Deprecated
public class ImageManager {

    @Resource
    private OssManager ossManager;
    @Resource
    private OssClientConfig ossClientConfig;

    /**
     * 上传图片 + 解析图片
     *
     * @param multipartFile    文件
     * @param uploadPathPrefix 上传路径前缀，例如：test/xxx.png 中的 test
     * @return 返回图片解析之后的信息
     */
    public ImageParseResult uploadAndParseImage(MultipartFile multipartFile, String uploadPathPrefix) {
        // 校验图片（大小以及类型）
        validImage(multipartFile);
        // 图片上传地址（拼接图片的名称以及相对路径）
        String uuid = RandomUtil.randomString(16); // 16位随机数
        String originFilename = multipartFile.getOriginalFilename(); // 原文件名
        String uploadFileName = String.format("%s_%s.%s", DateUtil.formatDate(new Date()), uuid, FileUtil.getSuffix(originFilename)); // 上传图片的名称（保证唯一）
        String uploadPath = String.format("%s/%s", uploadPathPrefix, uploadFileName); // 上传图片的相对路径，例如 test/xxx.png
        // 上传图片并返回图片信息
        File file = null;
        try {
            // 创建临时文件
            file = File.createTempFile(uploadPath, null);
            multipartFile.transferTo(file);
            // 上传图片
            ossManager.putObject(uploadPath, file);
            // 获取图片信息
            ImageInfoResult imageInfoResult = ossManager.getImageObject(uploadPath);
            ImageParseResult imageParseResult = ImageParseResult.imageInfoToParseVo(imageInfoResult);
            // 图片名
            imageParseResult.setName(FileUtil.mainName(originFilename));
            // 图片路径
            String url = String.format("%s.%s/%s", "https://" + ossClientConfig.getBucketName(), ossClientConfig.getEndpoint(), uploadPath);
            imageParseResult.setUrl(url);
            return imageParseResult;
        } catch (Exception e) {
            log.error("图片上传到对象存储失败", e);
            throw new BusinessException(ResponseCode.SYSTEM_ERROR, "上传失败");
        } finally {
            this.deleteTempFile(file);
        }
    }

    /**
     * 校验图片的大小和类型（非业务类的图片校验）
     *
     * @param multipartFile  文件
     */
    public void validImage(MultipartFile multipartFile) {
        // 校验文件是否为空
        ThrowUtils.throwIf(multipartFile == null, new BusinessException(ResponseCode.PARAMS_ERROR, "文件不能为空"));
        // 校验文件大小
        long fileSize = multipartFile.getSize();
        ThrowUtils.throwIf(fileSize > ImageConstant.FILE_SIZE_LIMIT, new BusinessException(ResponseCode.PARAMS_ERROR, "文件大小不能超过 2M"));
        // 获取文件的后缀
        String fileSuffix = FileUtil.getSuffix(multipartFile.getOriginalFilename());
        // 校验文件后缀，是否在 "jpeg", "jpg", "png", "webp" 中
        ThrowUtils.throwIf(!ImageConstant.ALLOW_UPLOAD_IMAGE_SUFFIX_FORMAT_LIST.contains(fileSuffix), new BusinessException(ResponseCode.PARAMS_ERROR, "文件类型错误"));
    }

    /**
     * 删除临时文件
     *
     * @param file  临时文件
     */
    public void deleteTempFile(File file) {
        if (file == null) {
            return;
        }
        // 删除临时文件
        if (!file.delete()) {
            log.error("file delete error, filePath = {}", file.getAbsolutePath());
        }
    }
}